#include "StdAfx.h"
#include "TcpServer.h"

#include <boost/bind.hpp>
#include <Network/TcpPacket.h>
#include <Network/TcpConnection.h>
#include <Network/TcpPacketDispatcher.h>

TcpServer::TcpServer(TcpIoLoop& ioLoop, TcpConnectionEventHandler* eventHandler)
: ioLoop_(ioLoop)
, eventHandler_(eventHandler)
{
}

TcpServer::~TcpServer(void)
{
}

bool TcpServer::Start(std::string& ip, std::string& port)
{
	TcpConnection* newConnection(new TcpConnection(ioLoop_.Get(), eventHandler_));

	acceptor_.reset(new boost::asio::ip::tcp::acceptor(ioLoop_.Get()));
	boost::asio::ip::tcp::resolver resolver(ioLoop_.Get());
	boost::asio::ip::tcp::resolver::query query(ip, port);

    boost::system::error_code ec;
    boost::asio::ip::tcp::resolver::iterator itr = resolver.resolve(query, ec), end;
    if( itr == end )
    {
        return false;
    }

	boost::asio::ip::tcp::endpoint endpoint = *itr;
	acceptor_->open(endpoint.protocol());
	acceptor_->set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
	acceptor_->bind(endpoint);
	acceptor_->listen();

	acceptor_->async_accept(newConnection->GetSocket(),
		boost::bind(&TcpServer::OnAcceptCompleted, this, newConnection, 
		boost::asio::placeholders::error));

	return true;
}

void TcpServer::Stop()
{
	acceptor_->close();
}

void TcpServer::OnAcceptCompleted(TcpConnection* connection, const boost::system::error_code& e)
{
	if(!e)
	{
		connection->Start();
		eventHandler_->OnConnected(connection, e.value());

		TcpConnection* newConnection(new TcpConnection(ioLoop_.Get(), eventHandler_));

		acceptor_->async_accept(newConnection->GetSocket(),
			boost::bind(&TcpServer::OnAcceptCompleted, this, newConnection,
				boost::asio::placeholders::error));
	}
}
